package com.example.distortionmeter.domain

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.bluetooth.BluetoothSocket
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity.RESULT_OK
import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.app.ActivityCompat
import androidx.core.app.ActivityCompat.startActivityForResult
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getSystemService
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.util.UUID
import java.io.InputStream
import java.io.OutputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
import kotlin.math.max

// 定义一个蓝牙管理器类，继承自蓝牙配置文件的服务监听接口
// 需要传入上下文(Context)来获取系统服务
class BluetoothManager(
    val context: Context, // 上下文对象，用于访问系统服务
) : BluetoothProfile.ServiceListener { // 实现蓝牙服务监听接口

    // 定义回调接口，用于与UI层通信
    interface BluetoothCallback {
        fun onDeviceFound(device: BluetoothDevice)      // 发现新设备时调用
        fun onConnectionStateChanged(device: BluetoothDevice, state: Int) // 连接状态变化
        fun onDataReceived(
            thd: Float,
            freq: Float,
            rate: Float,
            gain: Float,
            wave: List<Float>
        )             // 收到数据时调用
        fun onError(errorMessage: String)               // 发生错误时调用
    }

    // 使用Handler在主线程更新UI（蓝牙操作通常需要在后台线程进行）
    private val handler = Handler(Looper.getMainLooper())

    // 蓝牙相关组件声明
    private var bluetoothAdapter: BluetoothAdapter? = null // 蓝牙适配器（核心控制类）
    private var bluetoothSocket: BluetoothSocket? = null    // 蓝牙通信套接字
    private var connectedDevice: BluetoothDevice? = null    // 当前连接的设备
    private var callback: BluetoothCallback? = null         // 回调接口实例
    private var inputStream: InputStream? = null             // 输入数据流
    private var outputStream: OutputStream? = null           // 输出数据流

    // 定义蓝牙服务的唯一标识UUID（通用串行总线服务Class ID）
    private val MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")


    // 创建广播接收器，监听系统蓝牙事件
    private val receiver = object : BroadcastReceiver() {
        @SuppressLint("MissingPermission")
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) { // 根据不同的广播动作处理
                BluetoothDevice.ACTION_FOUND -> { // 发现新设备时
                    val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
                    device?.let { // 非空时通过回调通知
                        callback?.onDeviceFound(it)
                    }
                }

                BluetoothAdapter.ACTION_STATE_CHANGED -> { // 蓝牙状态变化时
                    when (intent.getIntExtra(
                        BluetoothAdapter.EXTRA_STATE,
                        BluetoothAdapter.ERROR
                    )) {
                        BluetoothAdapter.STATE_OFF -> callback?.onError("蓝牙已关闭") // 蓝牙关闭
                        BluetoothAdapter.STATE_ON -> initializeBluetooth()          // 蓝牙开启后初始化
                    }
                }
            }
        }
    }

    // 初始化块，在对象创建时执行
    init {
        initializeBluetooth()   // 初始化蓝牙适配器
        registerReceivers()    // 注册广播接收器
    }

    // 设置回调接口的方法
    fun setCallback(callback: BluetoothCallback) {
        this.callback = callback
    }

    // 初始化蓝牙适配器
    @SuppressLint("ServiceCast")
    private fun initializeBluetooth() {
        val bluetoothManager =
            context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        // 移除强制错误提示的逻辑，改为静默处理
        bluetoothAdapter = bluetoothManager.adapter
        if (bluetoothAdapter == null) {
            Log.w("BluetoothManager", "蓝牙适配器不可用或未启用")
            return
        }
    }


    // 开始搜索设备（需要蓝牙权限）
    @SuppressLint("MissingPermission")
    fun startDiscovery() {
        // 如果正在搜索则先取消
        if (bluetoothAdapter?.isDiscovering == true) {
            bluetoothAdapter?.cancelDiscovery()
        }

        // 启动设备搜索
        try {
            bluetoothAdapter?.startDiscovery()
        } catch (e: SecurityException) {
            callback?.onError("缺少蓝牙权限")
        } catch (e: IllegalStateException) {
            callback?.onError("蓝牙适配器不可用")
        }
    }

    // ======================= 设备连接 =======================
    // 连接到指定设备
    @SuppressLint("MissingPermission")
    fun connectToDevice(device: BluetoothDevice) {
        if (device == connectedDevice) {
            handler.post {
                callback?.onError("设备已连接")
            }
            return
        }

        bluetoothAdapter?.cancelDiscovery() // 停止搜索
        callback?.onConnectionStateChanged(device, STATE_CONNECTING) // 通知连接开始

        // 创建新线程进行连接操作（网络操作不能在主线程执行）
        Thread {
            try {
                // 创建RFCOMM套接字（蓝牙串口通信）
                val socket = device.createRfcommSocketToServiceRecord(MY_UUID)
                socket.connect() // 建立连接

                // 连接成功后的设置
                connectedDevice = device
                bluetoothSocket = socket
                inputStream = socket.inputStream   // 获取输入流
                outputStream = socket.outputStream // 获取输出流

                // 在主线程通知连接成功
                handler.post {
                    callback?.onConnectionStateChanged(device, STATE_CONNECTED)
                }

                startListening() // 开始监听数据
            } catch (e: IOException) {
                // 连接失败处理
                handler.post {
                    callback?.onError("连接失败: ${e.message}")
                    callback?.onConnectionStateChanged(device, STATE_DISCONNECTED)
                }
                closeConnection()
            }
        }.start()
    }

    // 关闭连接并释放资源
    private var isManualDisconnect = false
    fun closeConnection(isManual: Boolean = false) {
        isManualDisconnect = isManual // 标记断开类型
        // 提前获取设备引用
        val closingDevice = connectedDevice

        stopListening()

        try {
            synchronized(this) {
                bluetoothSocket?.close()
                inputStream?.close()
                outputStream?.close()
            }
        } catch (e: IOException) {
            if (!isManualDisconnect) { // 仅非主动断开时记录错误
                Log.e("Bluetooth", "关闭异常", e)
            }
        } finally {
            synchronized(this) {
                bluetoothSocket = null
                connectedDevice = null
                inputStream = null
                outputStream = null
            }

            handler.post {
                closingDevice?.let {
                    callback?.onConnectionStateChanged(it, STATE_DISCONNECTED)
                }
            }
        }
    }


    // ===================== 数据收发 =========================
    // 发送消息到已连接设备
    fun sendMessage(message: String) {
        if (bluetoothSocket?.isConnected != true) {
            callback?.onError("未建立连接")
            return
        }

        try {
            // 将字符串转换为字节数组并写入输出流
            outputStream?.write(message.toByteArray())
            outputStream?.flush() // 立即发送
        } catch (e: IOException) {
            handler.post {
                callback?.onError("发送失败: ${e.message}")
                closeConnection()
            }
        }
    }


    // 开始监听接收数据
    private fun startListening() {
        Thread {
            val inputStream = inputStream ?: return@Thread
            val readBuffer = ByteArray(1024)
            var buffer = ByteArray(4096)
            var startIdx = 0
            var endIdx = 0

            try {
                loop@ while (!Thread.interrupted()) {
                    // 确保缓冲区有足够空间
                    if (buffer.size - endIdx < readBuffer.size) {
                        val availableData = endIdx - startIdx
                        when {
                            // 需要扩容
                            (buffer.size - availableData < readBuffer.size) -> {
                                val newSize = max(buffer.size * 2, availableData + readBuffer.size)
                                val newBuffer = ByteArray(newSize)
                                System.arraycopy(buffer, startIdx, newBuffer, 0, availableData)
                                buffer = newBuffer
                                startIdx = 0
                                endIdx = availableData
                            }
                            // 移动数据到前端
                            else -> {
                                System.arraycopy(buffer, startIdx, buffer, 0, availableData)
                                endIdx = availableData
                                startIdx = 0
                            }
                        }
                    }

                    // 读取数据
                    val bytesRead = inputStream.read(buffer, endIdx, buffer.size - endIdx)
                    when {
                        bytesRead == -1 -> break@loop // 流结束
                        bytesRead == 0 -> continue@loop // 无数据
                        else -> endIdx += bytesRead
                    }

                    // 包处理逻辑
                    while (endIdx - startIdx >= PACKET_SIZE) {
                        val packet = buffer.copyOfRange(startIdx, startIdx + PACKET_SIZE)

                        if (packet[0] == HEADER[0] && packet[1] == HEADER[1]) {
                            if (verifyPacket(packet)) {
                                processValidPacket(packet)
                                startIdx += PACKET_SIZE
                                continue // 成功处理，继续下一个包
                            }
                        }
                        // 无效包：移动一个字节重新同步
                        startIdx += 1
                    }

                    // 压缩缓冲区（当空闲空间超过50%）
                    if (startIdx > buffer.size / 2) {
                        System.arraycopy(buffer, startIdx, buffer, 0, endIdx - startIdx)
                        endIdx -= startIdx
                        startIdx = 0
                    }
                }
            } catch (e: IOException) {
                if (!isManualDisconnect) {
                    handler.post {
                        callback?.onError("连接中断: ${e.message}")
                        closeConnection()
                    }
                }
            } finally {
                closeConnection()
            }
        }.start()
    }


    private fun stopListening() {
        // 关闭输入流以中断阻塞的read()操作
        try {
            inputStream?.close()
        } catch (e: IOException) {
            // 忽略关闭异常
        }
    }

    // ===================== 数据处理 =========================
    private fun verifyPacket(packet: ByteArray): Boolean {
        if (packet.size < PACKET_SIZE) return false

        // 计算校验和
        var checksum = 0
        for (i in 0 until PACKET_SIZE - 1) {
            checksum = checksum xor (packet[i].toInt() and 0xFF)
        }
        return checksum == (packet.last().toInt() and 0xFF)
    }

    private fun processValidPacket(packet: ByteArray) {
        try {
            val byteBuffer = ByteBuffer.wrap(packet).apply {
                order(ByteOrder.LITTLE_ENDIAN) // 根据单片机端实际情况设置字节序
            }
            // 读取版本号
            val version = byteBuffer.get().toInt() and 0xFF // 读取包头后的版本号

            // 跳过包头和版本号
            byteBuffer.position(2)

            val thd = byteBuffer.float
            val freq = byteBuffer.float
            val rate = byteBuffer.float
            val gain = byteBuffer.float

            val data = List(34) { byteBuffer.float }// 20个波形数据和10个谐波数据

            handler.post {
                callback?.onDataReceived(thd, freq, rate, gain, data)
            }
        } catch (e: Exception) {
            handler.post { callback?.onError("数据解析失败") }
        }
    }

    // ===================== 权限管理 =========================
    // 修改getRequiredPermissions方法
    private fun getRequiredPermissions(isConnect: Boolean = false): Array<String> {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (isConnect) arrayOf(Manifest.permission.BLUETOOTH_CONNECT)
            else arrayOf(
                Manifest.permission.BLUETOOTH_SCAN,
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.ACCESS_FINE_LOCATION // 补充定位权限
            )
        } else {
            arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
        }
    }

    // 注册广播接收器
    private fun registerReceivers() {
        val filter = IntentFilter().apply {
            addAction(BluetoothDevice.ACTION_FOUND)        // 设备发现动作
            addAction(BluetoothAdapter.ACTION_STATE_CHANGED) // 蓝牙状态变化动作
        }
        context.registerReceiver(receiver, filter) // 注册接收器
    }

    // 释放资源方法
    fun release() {
        context.unregisterReceiver(receiver) // 注销广播接收器
        closeConnection()                   // 关闭连接
    }

    // 新增取消扫描方法
    @SuppressLint("MissingPermission")
    fun cancelDiscovery() {
        bluetoothAdapter?.cancelDiscovery()
    }

    // 以下是必须实现的接口方法（此处不需要具体实现）
    override fun onServiceConnected(profile: Int, proxy: BluetoothProfile?) {}
    override fun onServiceDisconnected(profile: Int) {}

    // 伴生对象定义连接状态常量
    companion object {
        // 请求码常量
        const val REQUEST_BLUETOOTH = 1001
        const val REQUEST_DISCOVERY = 1002
        const val REQUEST_ENABLE_BT = 1
        const val REQUEST_LOCATION_PERMISSION = 2

        // 连接状态常量
        const val STATE_DISCONNECTED = 0  // 未连接
        const val STATE_CONNECTING = 1    // 正在连接
        const val STATE_CONNECTED = 2     // 已连接

        // 信息
        val HEADER = byteArrayOf(0xA5.toByte(), 0x01.toByte()) // 包头是A5 01
        const val PACKET_SIZE = 155 // 根据实际协议调整
    }
}